دليل شامل لتطبيق نماذج المستخدمين المخصصة في جانغو، لتعزيز المصادقة لتلبية متطلبات التطبيقات العالمية المتنوعة. تعلم أفضل الممارسات والتقنيات المتقدمة.
مصادقة بايثون جانغو: إتقان نماذج المستخدمين المخصصة للتطبيقات العالمية
يُعد نظام المصادقة المدمج في جانغو نقطة انطلاق قوية للعديد من تطبيقات الويب. ومع ذلك، عندما يتوسع تطبيقك ويصبح أكثر تعقيدًا، خاصةً لجمهور عالمي، قد لا يكون نموذج المستخدم الافتراضي كافيًا. هنا يأتي دور نماذج المستخدمين المخصصة، التي توفر مرونة وتحكمًا أكبر في بيانات المستخدم وعمليات المصادقة. سيرشدك هذا الدليل الشامل خلال عملية إنشاء وتطبيق نماذج المستخدمين المخصصة في جانغو، مما يضمن أن تطبيقك مجهز جيدًا للتعامل مع متطلبات المستخدم المتنوعة والاعتبارات الأمنية.
لماذا نستخدم نموذج مستخدم مخصصًا؟
تم تصميم نموذج المستخدم الافتراضي في جانغو بخصائص مشتركة مثل اسم المستخدم (username) وكلمة المرور (password) والبريد الإلكتروني (email) والاسم الأول (first_name) والاسم الأخير (last_name). وعلى الرغم من أنه مناسب للتطبيقات البسيطة، إلا أنه غالبًا ما يقصر عندما تحتاج إلى:
- تخزين معلومات مستخدم إضافية: فكر في منصة تجارة إلكترونية عالمية تحتاج إلى تخزين تفضيلات المستخدم، أو عناوين بتنسيقات مختلفة، أو عملات مفضلة، أو إعدادات لغوية. هذه تتجاوز نطاق النموذج الافتراضي.
- تغيير حقل المصادقة: ربما ترغب في مصادقة المستخدمين باستخدام عنوان بريدهم الإلكتروني بدلاً من اسم المستخدم، أو تطبيق مصادقة متعددة العوامل تتطلب حقولًا إضافية.
- الدمج مع قواعد البيانات الحالية: إذا كنت تقوم بدمج تطبيق جانغو مع قاعدة بيانات موجودة لها مخطط مستخدم مختلف، فإن نموذج المستخدم المخصص يسمح لك بربط نموذجك بهيكل البيانات الحالي.
- تعزيز الأمان: تسمح النماذج المخصصة بتحكم أكبر في تجزئة كلمات المرور (password hashing)، وآليات إعادة تعيين كلمة المرور، والجوانب الأخرى المتعلقة بالأمان.
- تطبيق أدوار مستخدمين مختلفة: يتيح تخزين بيانات التحكم في الوصول المستند إلى الأدوار (RBAC) مباشرة في النموذج (أو الإشارة إليها) تحكمًا أكثر مرونة ووضوحًا من المجموعات والأذونات العامة.
يوفر استخدام نموذج مستخدم مخصص طريقة نظيفة وقابلة للصيانة لتوسيع ملف تعريف المستخدم دون تعديل نظام المصادقة الأساسي في جانغو مباشرة. إنها أفضل ممارسة لأي مشروع يتوقع نموًا مستقبليًا أو يتطلب بيانات مستخدم متخصصة.
متى يجب تطبيق نموذج مستخدم مخصص؟
أفضل وقت لتطبيق نموذج مستخدم مخصص هو في بداية مشروعك. قد يكون تغيير نموذج المستخدم في بيئة إنتاج معقدًا وقد يؤدي إلى إتلاف البيانات. إذا كان مشروعك قيد التنفيذ بالفعل، ففكر مليًا في التداعيات وقم بإنشاء خطة ترحيل قوية قبل إجراء أي تغييرات.
إليك إرشادات عامة:
- ابدأ بنموذج مستخدم مخصص: إذا كنت تتوقع أي حاجة لمعلومات مستخدم موسعة أو منطق مصادقة مخصص.
- فكر في الترحيل بعناية: إذا كان لديك مشروع جانغو يعمل بالفعل مع مستخدمين وقررت التبديل إلى نموذج مخصص. قم بعمل نسخة احتياطية من قاعدة بياناتك وافهم عملية الترحيل جيدًا.
إنشاء نموذج مستخدم مخصص
هناك طريقتان رئيسيتان لإنشاء نموذج مستخدم مخصص في جانغو:
- AbstractBaseUser: يمنحك هذا النهج تحكمًا كاملاً في نموذج المستخدم. تقوم بتعريف جميع الحقول، بما في ذلك اسم المستخدم وكلمة المرور والبريد الإلكتروني وأي حقول مخصصة تحتاجها.
- AbstractUser: يرث هذا النهج من نموذج المستخدم الافتراضي في جانغو ويسمح لك بإضافة حقول موجودة أو تجاوزها. هذا أبسط إذا كنت تحتاج فقط إلى إضافة بعض الحقول الإضافية.
1. استخدام AbstractBaseUser (تحكم كامل)
هذا هو الخيار الأكثر مرونة، حيث يسمح لك بتعريف نموذج المستخدم بالكامل من البداية. يوفر أكبر قدر من التحكم في بنية بيانات المستخدم وعملية المصادقة. إليك الطريقة:
الخطوة 1: إنشاء نموذج مستخدم مخصص
في تطبيق جانغو الخاص بك (على سبيل المثال، 'accounts')، أنشئ ملف `models.py` وعرّف نموذج المستخدم المخصص الخاص بك الذي يرث من `AbstractBaseUser` و `PermissionsMixin`:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
class CustomUserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError('The Email field must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self.create_user(email, password, **extra_fields)
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True, verbose_name='email address')
first_name = models.CharField(max_length=150, blank=True)
last_name = models.CharField(max_length=150, blank=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(auto_now_add=True)
# Custom fields (Example: preferred language, timezone, etc.)
preferred_language = models.CharField(max_length=10, default='en', choices=[('en', 'English'), ('fr', 'French'), ('es', 'Spanish')])
timezone = models.CharField(max_length=50, default='UTC')
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = [] # Required when creating a superuser
objects = CustomUserManager()
def __str__(self):
return self.email
شرح:
- CustomUserManager: هذه الفئة مطلوبة لإدارة نموذج المستخدم المخصص الخاص بك. تتعامل مع إنشاء المستخدمين والمستخدمين الخارقين. يعد `normalize_email` مهمًا لضمان اتساق البريد الإلكتروني عبر اللغات المختلفة وطرق الإدخال.
- CustomUser: هذا هو نموذج المستخدم المخصص الخاص بك.
- `email = models.EmailField(unique=True, verbose_name='email address')`: يعرّف حقل البريد الإلكتروني كمُعرِّف فريد للمستخدم. يضمن استخدام `unique=True` أن كل مستخدم لديه عنوان بريد إلكتروني فريد. يحسن الاسم التوضيحي (verbose name) واجهة الإدارة.
- `first_name`, `last_name`: حقول قياسية لتخزين اسم المستخدم. يسمح `blank=True` بأن تكون هذه الحقول فارغة.
- `is_staff`, `is_active`: حقول قياسية للتحكم في وصول المستخدم إلى لوحة الإدارة وتفعيل الحساب.
- `date_joined`: يسجل تاريخ إنشاء حساب المستخدم.
- `preferred_language`, `timezone`: أمثلة على حقول مخصصة لتخزين تفضيلات المستخدم. تحدد الوسيطة `choices` خيارات اللغة الممكنة. هذا أمر بالغ الأهمية لتطبيق عالمي. المنطقة الزمنية مهمة أيضًا للترجمة.
- `USERNAME_FIELD = 'email'`: يحدد أن حقل البريد الإلكتروني سيُستخدم كاسم مستخدم للمصادقة.
- `REQUIRED_FIELDS = []`: يحدد الحقول المطلوبة عند إنشاء مستخدم خارق باستخدام أمر `createsuperuser`. في هذه الحالة، لا توجد حقول إضافية مطلوبة بخلاف البريد الإلكتروني وكلمة المرور.
- `objects = CustomUserManager()`: يعين مدير المستخدم المخصص للنموذج.
- `__str__(self)`: يحدد كيفية تمثيل كائن المستخدم كسلسلة نصية (على سبيل المثال، في لوحة الإدارة).
الخطوة 2: تحديث `settings.py`
أخبر جانغو باستخدام نموذج المستخدم المخصص الخاص بك عن طريق إضافة السطر التالي إلى ملف `settings.py` الخاص بك:
AUTH_USER_MODEL = 'accounts.CustomUser'
استبدل `accounts` باسم تطبيقك حيث قمت بتعريف نموذج `CustomUser`.
الخطوة 3: إنشاء وتطبيق الترحيلات (Migrations)
قم بتشغيل الأوامر التالية لإنشاء وتطبيق الترحيلات:
python manage.py makemigrations
python manage.py migrate
سيؤدي هذا إلى إنشاء جدول قاعدة بيانات جديد لنموذج المستخدم المخصص الخاص بك.
الخطوة 4: استخدام نموذج المستخدم المخصص
يمكنك الآن استخدام نموذج المستخدم المخصص الخاص بك في قوالبك، وعروضك، وأجزاء أخرى من تطبيقك. على سبيل المثال، لإنشاء مستخدم جديد:
from accounts.models import CustomUser
user = CustomUser.objects.create_user(email='user@example.com', password='password123', first_name='John', last_name='Doe')
2. استخدام AbstractUser (الإضافة إلى النموذج الافتراضي)
هذا النهج أبسط إذا كنت تحتاج فقط إلى إضافة عدد قليل من الحقول الإضافية إلى نموذج المستخدم الافتراضي في جانغو. إنه يرث جميع الحقول والأساليب الموجودة من `AbstractUser`. قد يكون هذا أسهل للتخصيصات البسيطة.
الخطوة 1: إنشاء نموذج مستخدم مخصص
في ملف `models.py` لتطبيق جانغو الخاص بك، عرّف نموذج المستخدم المخصص الخاص بك الذي يرث من `AbstractUser`:
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
# Add extra fields here
phone_number = models.CharField(max_length=20, blank=True, verbose_name='Phone Number')
profile_picture = models.ImageField(upload_to='profile_pictures/', blank=True)
# Custom fields (Example: preferred currency, address format, etc.)
preferred_currency = models.CharField(max_length=3, default='USD', choices=[('USD', 'US Dollar'), ('EUR', 'Euro'), ('JPY', 'Japanese Yen')])
address_format = models.CharField(max_length=50, blank=True, help_text='e.g., "Name, Street, City, Zip, Country"')
def __str__(self):
return self.username
شرح:
- CustomUser: هذا هو نموذج المستخدم المخصص الخاص بك، ويرث من `AbstractUser`.
- `phone_number`, `profile_picture`: أمثلة لحقول تُضاف إلى نموذج المستخدم. تحدد `upload_to` مكان تخزين صور الملف الشخصي.
- `preferred_currency`, `address_format`: أمثلة على حقول مخصصة ذات صلة بالتطبيقات العالمية. تختلف تنسيقات العناوين اختلافًا جذريًا بين البلدان.
- `__str__(self)`: يحدد كيفية تمثيل كائن المستخدم كسلسلة نصية (على سبيل المثال، في لوحة الإدارة). هنا يستخدم اسم المستخدم.
الخطوة 2: تحديث `settings.py`
كما كان من قبل، أخبر جانغو باستخدام نموذج المستخدم المخصص الخاص بك عن طريق إضافة السطر التالي إلى ملف `settings.py` الخاص بك:
AUTH_USER_MODEL = 'accounts.CustomUser'
الخطوة 3: إنشاء وتطبيق الترحيلات (Migrations)
قم بتشغيل الأوامر التالية لإنشاء وتطبيق الترحيلات:
python manage.py makemigrations
python manage.py migrate
الخطوة 4: استخدام نموذج المستخدم المخصص
يمكنك الآن الوصول إلى الحقول المضافة عند العمل مع كائنات المستخدمين:
from accounts.models import CustomUser
user = CustomUser.objects.create_user(username='johndoe', password='password123', email='john.doe@example.com')
user.phone_number = '+15551234567'
user.preferred_currency = 'EUR'
user.save()
أفضل الممارسات لنماذج المستخدمين المخصصة في التطبيقات العالمية
عند تطبيق نماذج مستخدمين مخصصة للتطبيقات التي تستهدف جمهورًا عالميًا، ضع في اعتبارك أفضل الممارسات التالية:
1. التدويل والتعريب (i18n & l10n)
تخزين البيانات الخاصة باللغة والمنطقة: صمم نموذجك لاستيعاب الأعراف الثقافية المختلفة وتنسيقات البيانات. قم بتخزين التواريخ والأوقات والأرقام والعناوين بطريقة تراعي اللغة والمنطقة.
مثال:
from django.utils import timezone
class CustomUser(AbstractUser):
#...
date_of_birth = models.DateField(blank=True, null=True)
def get_localized_date_of_birth(self, language_code):
if self.date_of_birth:
return timezone.localtime(timezone.make_aware(datetime.datetime.combine(self.date_of_birth, datetime.time.min))).strftime('%x') # Format according to the locale
return None
2. التعامل مع المناطق الزمنية
قم دائمًا بتخزين المناطق الزمنية والتعامل معها بشكل صحيح. قم بتخزين معلومات المنطقة الزمنية في نموذج المستخدم واستخدمها لعرض التواريخ والأوقات في المنطقة الزمنية المحلية للمستخدم.
مثال:
from django.utils import timezone
class CustomUser(AbstractUser):
#...
timezone = models.CharField(max_length=50, default='UTC')
def get_localized_time(self, datetime_obj):
user_timezone = pytz.timezone(self.timezone)
return timezone.localtime(datetime_obj, user_timezone)
3. تنسيق العناوين
تختلف تنسيقات العناوين بشكل كبير بين البلدان. قم بتطبيق نظام عناوين مرن يسمح للمستخدمين بإدخال عناوينهم بالتنسيق الصحيح لموقعهم. فكر في استخدام مكتبة أو خدمة خارجية للتعامل مع التحقق من صحة العناوين وتنسيقها.
مثال:
class CustomUser(AbstractUser):
#...
country = models.CharField(max_length=50, blank=True)
address_line_1 = models.CharField(max_length=255, blank=True)
address_line_2 = models.CharField(max_length=255, blank=True)
city = models.CharField(max_length=100, blank=True)
postal_code = models.CharField(max_length=20, blank=True)
def get_formatted_address(self):
# Implement logic to format address based on country
if self.country == 'US':
return f'{self.address_line_1}\n{self.address_line_2}\n{self.city}, {self.postal_code}, {self.country}'
elif self.country == 'GB':
return f'{self.address_line_1}\n{self.address_line_2}\n{self.city}\n{self.postal_code}\n{self.country}'
else:
return 'Address format not supported'
4. التعامل مع العملات
إذا كان تطبيقك يتضمن معاملات مالية، فقم بتخزين العملة المفضلة للمستخدم واستخدمها لعرض الأسعار والمبالغ. استخدم مكتبة مثل `babel` لتنسيق قيم العملات وفقًا للغة والمنطقة الخاصة بالمستخدم.
مثال:
from babel.numbers import format_currency
class CustomUser(AbstractUser):
#...
preferred_currency = models.CharField(max_length=3, default='USD')
def get_formatted_price(self, amount):
return format_currency(amount, self.preferred_currency, locale='en_US') # Adjust locale as needed
5. التحقق من صحة البيانات
قم بتطبيق تحقق قوي من صحة البيانات لضمان أن مدخلات المستخدم صالحة ومتسقة. استخدم أدوات التحقق المضمنة في جانغو أو أنشئ أدوات تحقق مخصصة لفرض سلامة البيانات.
مثال:
from django.core.validators import RegexValidator
class CustomUser(AbstractUser):
#...
phone_number = models.CharField(
max_length=20,
blank=True,
validators=[
RegexValidator(
regex=r'^\+?\d{9,15}$',
message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed."
),
]
)
6. اعتبارات الأمان
تجزئة كلمة المرور: يستخدم نظام مصادقة جانغو خوارزميات تجزئة كلمات مرور قوية بشكل افتراضي. تأكد من أنك تستخدم أحدث إصدار من جانغو للاستفادة من آخر تحديثات الأمان.
المصادقة الثنائية (2FA): قم بتطبيق المصادقة الثنائية لإضافة طبقة أمان إضافية لحسابات المستخدمين. تتوفر العديد من حزم جانغو لهذا الغرض، مثل `django-otp`. هذا مهم بشكل خاص عند التعامل مع بيانات المستخدم الحساسة أو المعاملات المالية.
حماية البيانات: اتبع أفضل الممارسات لحماية البيانات والخصوصية، خاصة عند التعامل مع معلومات المستخدم الحساسة. امتثل للوائح حماية البيانات ذات الصلة، مثل اللائحة العامة لحماية البيانات (GDPR) وقانون خصوصية المستهلك في كاليفورنيا (CCPA). ضع في اعتبارك تقنيات تشفير البيانات، إخفاء الهوية، والترميز.
7. الاختبار
اكتب اختبارات وحدة شاملة واختبارات تكامل لضمان أن نموذج المستخدم المخصص يعمل كما هو متوقع وأن نظام المصادقة الخاص بك آمن. اختبر سيناريوهات مختلفة، بما في ذلك مدخلات المستخدم الصالحة وغير الصالحة، وسير عمل إعادة تعيين كلمة المرور، وفحوصات الأذونات.
8. التوثيق
وثّق نموذج المستخدم المخصص ونظام المصادقة الخاص بك بشكل شامل. سيجعل هذا الأمر أسهل للمطورين الآخرين لفهم وصيانة التعليمات البرمجية الخاصة بك. قم بتضمين معلومات حول الغرض من كل حقل، وسير عمل المصادقة، وأي اعتبارات أمنية.
تقنيات واعتبارات متقدمة
1. مدراء المستخدمين المخصصون
كما هو موضح في مثال `AbstractBaseUser`، فإن مدراء المستخدمين المخصصين ضروريون لإنشاء وإدارة المستخدمين. يسمحون لك بتعريف منطق مخصص لإنشاء المستخدمين، مثل تعيين قيم افتراضية لحقول معينة أو إجراء تحقق إضافي.
2. نماذج الوكيل (Proxy Models)
تسمح نماذج الوكيل بإضافة أساليب إلى نموذج المستخدم دون تغيير مخطط قاعدة البيانات. يمكن أن يكون هذا مفيدًا لإضافة منطق أو حسابات مخصصة لتطبيقك.
3. توسيع نموذج المستخدم بنموذج ملف شخصي
بدلاً من إضافة العديد من الحقول مباشرة إلى نموذج المستخدم، يمكنك إنشاء نموذج ملف شخصي منفصل له علاقة واحد لواحد مع نموذج المستخدم. هذا يمكن أن يساعد في الحفاظ على نموذج المستخدم الخاص بك نظيفًا ومنظمًا.
from django.db import models
from django.conf import settings
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='profile')
# Additional fields
bio = models.TextField(blank=True)
location = models.CharField(max_length=100, blank=True)
تذكر إنشاء إشارة لإنشاء UserProfile تلقائيًا عند إنشاء مستخدم:
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings
from .models import UserProfile
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
4. تسجيل الدخول الموحد (SSO)
بالنسبة للمؤسسات الكبيرة أو التطبيقات التي تتطلب التكامل مع خدمات أخرى، فكر في تطبيق تسجيل الدخول الموحد (SSO) باستخدام بروتوكولات مثل OAuth 2.0 أو SAML. يوفر جانغو العديد من الحزم التي تبسط تكامل SSO، مثل `django-allauth`.
5. سجل التدقيق
قم بتطبيق سجل التدقيق لتتبع نشاط المستخدم والتغييرات على بيانات المستخدم. يمكن أن يكون هذا مفيدًا لمراقبة الأمان والامتثال والتصحيح. يمكن أن تساعد حزم مثل `django-auditlog` في أتمتة هذه العملية.
الخاتمة
يوفر إنشاء وتطبيق نماذج مستخدمين مخصصة في جانغو المرونة والتحكم الذي تحتاجه لبناء أنظمة مصادقة قوية وقابلة للتطوير، خاصة للتطبيقات العالمية. باتباع أفضل الممارسات الموضحة في هذا الدليل، يمكنك ضمان أن تطبيقك مجهز جيدًا للتعامل مع متطلبات المستخدم المتنوعة، والحفاظ على سلامة البيانات، وتوفير تجربة آمنة وسهلة الاستخدام للمستخدمين حول العالم. تذكر أن تخطط لتطبيقك بعناية، وتأخذ في الاعتبار احتياجات المستخدمين، وتولي الأولوية للأمان في كل مرحلة من مراحل العملية. يعتمد الاختيار بين `AbstractBaseUser` و `AbstractUser` على مستوى التخصيص المطلوب. للتغييرات الكبيرة، يوفر `AbstractBaseUser` مزيدًا من التحكم. للتوسعات البسيطة، يوفر `AbstractUser` انتقالًا أكثر سلاسة. يعد الاختبار الشامل أمرًا بالغ الأهمية لضمان تكامل نموذج المستخدم المخصص بسلاسة مع بقية تطبيق جانغو الخاص بك ويلبي جميع متطلبات الأمان. تبنى أفضل الممارسات للتدويل والتعريب والتعامل مع المناطق الزمنية لتقديم تجربة عالمية حقيقية. سيساهم هذا بشكل كبير في نجاح تطبيقك واعتماده في أسواق متنوعة حول العالم.